package com.yfp.operation.controller;

import cn.hutool.core.lang.Assert;
import com.yfp.common.core.constant.CacheConstants;
import com.yfp.common.core.domain.R;
import com.yfp.common.core.web.controller.BaseController;
import com.yfp.common.core.web.page.TableDataInfo;
import com.yfp.common.log.annotation.Log;
import com.yfp.common.log.enums.BusinessType;
import com.yfp.operation.domain.MarCouponPack;
import com.yfp.operation.domain.MarCouponPackShop;
import com.yfp.operation.domain.TagCombo;
import com.yfp.operation.domain.vo.MarCouponPackInfoVO;
import com.yfp.operation.service.MarCouponPackService;
import com.yfp.operation.service.MarCouponPackShopService;
import com.yfp.operation.utils.RedisDistributedLock;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.RedissonMultiLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Description: 礼包销售
 *
 * @CreateDate: 2024/10/22 11:03
 * @UpdateUser:
 * @UpdateDate: 2024/10/22 11:03
 * @UpdateRemark: 暂无修改
 * @Version: 1.0
 */
@RestController
@RequestMapping("marCouponPackShop")
@Tag(name = "礼包销售-pc")
@Slf4j
public class MarCouponPackShopController extends BaseController {
    @Resource
    private MarCouponPackShopService marCouponPackShopService;
    @Resource
    private MarCouponPackService marCouponPackService;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private RedisTemplate redisTemplate;

    @PostMapping
    @Operation(summary = "创建礼包销售")
    @Log(title = "pc-创建礼包销售", businessType = BusinessType.INSERT)
    public R<Void> create(@RequestBody MarCouponPackShop marCouponPackShop) throws InterruptedException {
        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, CacheConstants.MAR_COUPON_PACKSHOP_LOCK_KEY + marCouponPackShop.getCouponPackId(), 5);
        try {
            // 加锁
            redisDistributedLock.lock();
            logger.info("创建礼包销售");
            MarCouponPack marCouponPack = marCouponPackService.findById(marCouponPackShop.getCouponPackId());
            if (marCouponPack.getStatus() != 1){
                redisDistributedLock.unlock();
                return R.fail("该礼包状态不是进行中！");
            } else if (marCouponPack.getSurplusCount() < marCouponPackShop.getPackNum()){
                redisDistributedLock.unlock();
                return R.fail("该礼包库存不足！");
            }

            List<MarCouponPackShop> bySortAndStatus = marCouponPackShopService.findBySortAndStatus(marCouponPackShop.getSort(), 1, marCouponPackShop.getCityName());
            List<MarCouponPackShop> marCouponPackShops = marCouponPackShopService.findBySortAndStatus(marCouponPackShop.getSort(), 3, marCouponPackShop.getCityName());
            bySortAndStatus.addAll(marCouponPackShops);

            if (!CollectionUtils.isEmpty(bySortAndStatus)){
                redisDistributedLock.unlock();
                return R.fail("该礼包的排序已存在！");
            }
            TagCombo tagCombo = marCouponPackShopService.findTagComboById(marCouponPackShop.getTagId());
            if (null != tagCombo && tagCombo.getEnable() == 0){
                redisDistributedLock.unlock();
                return R.fail("该礼包的标签已被禁用！");
            }

            MarCouponPackShop marCouponPackShop1 = marCouponPackShopService.findByPackId(marCouponPackShop.getCouponPackId(), 1);
            if (null != marCouponPackShop1){
                redisDistributedLock.unlock();
                return R.fail("此礼包正在售卖中，请勿重复选择！");
            }

            marCouponPackShopService.create(marCouponPackShop);
            redisDistributedLock.unlock();
        } catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
            redisDistributedLock.unlock();
            return R.fail("稍后重试！！");
        }
        return R.ok();
    }

    @PostMapping("/merchandize/{id}")
    @Operation(summary = "上架礼包销售")
    @Log(title = "pc-上架礼包销售", businessType = BusinessType.UPDATE)
    public R<Void> merchandize(@PathVariable Long id) {

        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, CacheConstants.MAR_COUPON_PACKSHOP_LOCK_KEY + id, 5);
        try {
            // 加锁
            redisDistributedLock.lock();
            MarCouponPackShop marCouponPackShop = marCouponPackShopService.findById(id);
            MarCouponPack marCouponPack = marCouponPackService.findById(marCouponPackShop.getCouponPackId());
            if (marCouponPack.getStatus() != 1){
                redisDistributedLock.unlock();
                return R.fail("该礼包状态不是进行中！");
            } else if (marCouponPackShop.getCurrentStock() == 0L && marCouponPack.getSurplusCount() < marCouponPackShop.getPackNum()){
                redisDistributedLock.unlock();
                return R.fail("该礼包库存不足！");
            }

            List<MarCouponPackShop> bySortAndStatus = marCouponPackShopService.findBySortAndStatus(marCouponPackShop.getSort(), 1, marCouponPackShop.getCityName());
            List<MarCouponPackShop> marCouponPackShops = marCouponPackShopService.findBySortAndStatus(marCouponPackShop.getSort(), 3, marCouponPackShop.getCityName());
            bySortAndStatus.addAll(marCouponPackShops);

            for (MarCouponPackShop sortAndStatus : bySortAndStatus) {
                if (!sortAndStatus.getId().equals(id)){
                    redisDistributedLock.unlock();
                    return R.fail("该礼包的排序已存在！");
                }
            }

            TagCombo tagCombo = marCouponPackShopService.findTagComboById(marCouponPackShop.getTagId());
            if (null != tagCombo && tagCombo.getEnable() == 0){
                redisDistributedLock.unlock();
                return R.fail("该礼包的标签已被禁用！");
            }

            MarCouponPackShop marCouponPackShop1 = marCouponPackShopService.findByPackId(marCouponPackShop.getCouponPackId(), 1);
            if (null != marCouponPackShop1){
                redisDistributedLock.unlock();
                return R.fail("此礼包正在售卖中，请勿重复选择！");
            }
            marCouponPackShopService.merchandize(id);
            redisDistributedLock.unlock();
            return R.ok();
        } catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            redisDistributedLock.unlock();
        }
        return R.fail();
    }

    @PostMapping("/unshelve/{id}")
    @Operation(summary = "下架礼包销售")
    @Log(title = "pc-下架礼包销售", businessType = BusinessType.UPDATE)
    public R<Void> unshelve(@PathVariable Long id) {
        marCouponPackShopService.unshelve(id);
        return R.ok();
    }

    @GetMapping
    @Operation(summary = "查询礼包销售列表")
    public R<TableDataInfo<MarCouponPackShop>> listCouponPack(MarCouponPackShop marCouponPackShop) {
        startPage();
        List<MarCouponPackShop> list = marCouponPackShopService.list(marCouponPackShop);
        TableDataInfo dataTable = getDataTable(list);
        return R.ok(dataTable);
    }


    @GetMapping("/{id}")
    @Operation(summary = "查询礼包销售详情")
    public R<MarCouponPackShop> findById(@PathVariable Long id) {
        MarCouponPackShop marCouponPackVOS = marCouponPackShopService.findById(id);
        MarCouponPack marCouponPack = marCouponPackService.findById(marCouponPackVOS.getCouponPackId());
        marCouponPackVOS.setPackSurplusCount(marCouponPack.getSurplusCount());
        return R.ok(marCouponPackVOS);
    }

    @GetMapping("/findSort")
    @Operation(summary = "查询礼包排序")
    public R<Integer> findSort(@RequestParam("cityName") String cityName) {
        return R.ok(marCouponPackShopService.findSort(cityName));
    }

    @PutMapping("")
    @Operation(summary = "编辑礼包销售")
    @Log(title = "pc-编辑礼包销售", businessType = BusinessType.UPDATE)
    public R<MarCouponPackInfoVO> editCouponPack(@RequestBody  MarCouponPackShop marCouponPackShop) {
        RedisDistributedLock redisDistributedLock = new RedisDistributedLock(redisTemplate, CacheConstants.MAR_COUPON_PACKSHOP_LOCK_KEY + marCouponPackShop.getCouponPackId(), 5);
        try {
            redisDistributedLock.lock();
            if (marCouponPackShop.getStatus() != -1){
                MarCouponPack marCouponPack = marCouponPackService.findById(marCouponPackShop.getCouponPackId());

                if (marCouponPack.getStatus() != 1){
                    redisDistributedLock.unlock();
                    return R.fail("该礼包状态不是进行中！");
                } else if (marCouponPack.getSurplusCount() < marCouponPackShop.getPackNum() - marCouponPackShop.getCurrentStock() ){
                    redisDistributedLock.unlock();
                    return R.fail("该礼包库存不足！");
                }
                List<MarCouponPackShop> bySortAndStatus = marCouponPackShopService.findBySortAndStatus(marCouponPackShop.getSort(), 1, marCouponPackShop.getCityName());
                List<MarCouponPackShop> marCouponPackShops = marCouponPackShopService.findBySortAndStatus(marCouponPackShop.getSort(), 3, marCouponPackShop.getCityName());
                bySortAndStatus.addAll(marCouponPackShops);

                for (MarCouponPackShop sortAndStatus : bySortAndStatus) {
                    if (!sortAndStatus.getId().equals(marCouponPackShop.getId())){
                        redisDistributedLock.unlock();
                        return R.fail("该礼包的排序已存在！");
                    }
                }
                TagCombo tagCombo = marCouponPackShopService.findTagComboById(marCouponPackShop.getTagId());
                if (null != tagCombo && tagCombo.getEnable() == 0){
                    redisDistributedLock.unlock();
                    return R.fail("该礼包的标签已被禁用！");
                }
            }
        } catch (Exception e){
            redisDistributedLock.unlock();
            return R.fail("稍后重试！");
        }
        marCouponPackShopService.edit(marCouponPackShop);
        redisDistributedLock.unlock();
        return R.ok();
    }
}
